//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   PowerIter.hh
 * \author Jeremy Roberts
 * \date   11/23/2010
 * \brief  Base class for local problem routines.
 * \note   Copyright (C) 2010 Jeremy Roberts
 */
//---------------------------------------------------------------------------//
// $Rev::                                               $:Rev of last commit
// $Author::                                            $:Author of last commit
// $Date::                                              $:Date of last commit
//---------------------------------------------------------------------------//

#ifndef POWERITER_HH
#define POWERITER_HH

#include <iostream>
#include <cmath>
#include "LinAlg.hh"
#include "GlobalInput.hh"
#include "ResponseFunctionServer.hh"
#include "ResponseMatrix.hh"
#include "ResponseMatrixFull.hh"
#include "AbsorptionResponse.hh"
#include "FissionResponse.hh"
#include "LeakageResponse.hh"
#include "ConnectMatrix.hh"
#include "Connect2dCart.hh"
#include "GlobalProblem.hh"
#include "GlobalSolver.hh"

using namespace std;
//===========================================================================//
/*!
 * \class PowerIter
 * \brief This class solves GlobalProblems via use of power iterations.
 *
 * Acceleration via Aitken's method or Steffensen's method is available.  For 
 * the former, the Aitken estimate is printed with the actual value of 
 * \f$ k \f$.  The Steffensen approach uses the Aitken estimate to update the
 * the response quantities and thus the estimate becomes the actual value.
 *
 * The convergence criterion is currently limited to a nonlinear residual 
 * evaluation that makes comparison to Newton methods easier, though other
 * criteria (perhaps on \f$ k \f$ alone) could be used.
 *
 * The following is a "wish list" for the power method solver: 
 * <OL>
 *    <LI> acceleration for the vector, perhaps via Aiten or better yet,
 *         via Chebyshev extrapolation. </LI>
 *    <LI> better options for convergence criteria; the residual is fine
 *         for comparison, but that still requires a good way of converging
 *         the inners.  Moreover, a good way of setting the inner and outer 
 *         criteria is needed for a more general case without the residual </LI>
 *    <LI> more? </LI>
 * </OL>
 */
//===========================================================================//

class PowerIter : public GlobalSolver
{

  public:

    PowerIter( GlobalProblem &pr, GlobalInput &in );
    ~PowerIter();
    void Solve();

  protected: // <-- shouldn't these be private?
    // inherits
    //    GlobalProblem *problem;
    //    vector<scalar> keffHistory;
    //    vector<scalar> keffErrHistory;
    //    vector<scalar> curErrHistory;
    //    vector<scalar> residErrHistory;
    //    scalar wallTime;
    scalar normResid( SermentVector *J, scalar keff, scalar lambda );
    scalar lambda;// "current eigenvalue"
    scalar Aitken( scalar k0, scalar k1, scalar k2 );

};

#endif // POWERITER_HH

//---------------------------------------------------------------------------//
//                 end of PowerIter.hh
//---------------------------------------------------------------------------//

